package com.dwxt.cdms.listener;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dwxt.cdms.api.common.utils.StringUtil;
import com.dwxt.cdms.constant.EquipCategory;
import com.dwxt.cdms.constant.HealthParamCode;
import com.dwxt.cdms.constant.WarningType;
import com.dwxt.cdms.dao.*;
import com.dwxt.cdms.entity.*;
import com.dwxt.cdms.entity.laibang.LbWatchConvertor;
import com.dwxt.cdms.entity.laibang.LbWatchVO;
import com.dwxt.cdms.service.*;
import com.dwxt.cdms.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.net.URI;
import java.nio.channels.NotYetConnectedException;
import java.util.Date;

@Slf4j
public class LbWebSocketClient extends WebSocketClient {

    private long i = 0;

    @Autowired
    private LbWatchMapper lbWatchMapper;
    @Autowired
    private LbWatchDataMapper lbWatchDataMapper;
    @Autowired
    private EquipmentCustomService equipmentCustomService;
    @Autowired
    private LbWatchService lbWatchService;
    @Autowired
    private EquipmentService equipmentService;
    @Autowired
    private LbWatchLocMapper lbWatchLocMapper;
    @Autowired
    private ElectronicFenceService electronicFenceService;
    @Autowired
    private WarningService warningService;
    @Resource(name = "LbWebSocketClient")
    private LbWebSocketClient lbWebSocketClient;
    @Autowired
    private LbWatchWarnMapper lbWatchWarnMapper;
    @Autowired
    private CustomerService customerService;
    @Autowired
    private HealthService healthService;
    @Autowired
    private HealthWarnRecordMapper healthWarnRecordMapper;


    public LbWebSocketClient(URI serverUri) {
        super(serverUri);
    }

    @Override
    public void onOpen(ServerHandshake arg0) {
// TODO Auto-generated method stub
        log.info("------ MyWebSocket onOpen ------");
    }

    @Override
    public void onClose(int arg0, String arg1, boolean arg2) {
        // TODO Auto-generated method stub
        log.info("------ MyWebSocket onClose ------");
        log.info(arg1);
    }

    @Override
    public void onError(Exception arg0) {
        // TODO Auto-generated method stub
        log.info("------ MyWebSocket onError ------");
    }

    @Override
    public void onMessage(String arg0) {
        // TODO Auto-generated method stub
        log.info("接收到来邦数据： " + arg0);
        //第一次注册
        String req = "{\"req\":{\"clientType\":\"7\",\"id\":\"" + lbWatchService.getLaiBangToken() + "\"},\"action\":\"register\"}";
        if (i == 0) {
            this.send(req);
            i++;
        }
//        arg0 = "{\"msg\":\"SUCCESS\",\"msgType\":53,\"body\":\"{\\\"addAmbientBeaconDTO\\\":null,\\\"addBodyTemperatureDTO\\\":null,\\\"addDevicePowerDTOList\\\":[],\\\"addHealthDTO\\\":{\\\"bloodOxygen\\\":197,\\\"diastolicPressure\\\":255,\\\"heartRate\\\":75,\\\"measureTime\\\":1640051377,\\\"measureType\\\":1,\\\"sportStatus\\\":0,\\\"systolicPressure\\\":255},\\\"addHumitureDTO\\\":null,\\\"addPositionStatusDTOList\\\":[{\\\"duration\\\":0,\\\"status\\\":2,\\\"type\\\":7}],\\\"addSignalQualityDTO\\\":{\\\"rSRP\\\":34,\\\"rSRQ\\\":50,\\\"rSSI\\\":12},\\\"addWearStatusDTO\\\":{\\\"duration\\\":265,\\\"powerStatus\\\":0,\\\"status\\\":1},\\\"addWifiDTO\\\":{\\\"recordTime\\\":1640051287,\\\"wifiInfo\\\":\\\"48:0E:EC:64:73:2A,-207|54:75:95:5B:CD:9D,-179|70:8B:CD:AF:6D:E0,-168\\\"},\\\"deviceMac\\\":\\\"C1:FB:75:08:7F:48\\\",\\\"deviceType\\\":0,\\\"deviceVersion\\\":2,\\\"iotDeviceId\\\":\\\"52381428-0f2a-457e-b17f-1c46ce0098bc\\\",\\\"nbVersion\\\":-1,\\\"position\\\":\\\"00000000000000000000\\\",\\\"positionType\\\":0,\\\"power\\\":61,\\\"recordId\\\":\\\"133536185420742663\\\",\\\"reportTime\\\":1640051432}\",\"status\":\"200\",\"pushType\":\"orgId\"}\n";
//        arg0 = "{\"msg\":\"SUCCESS\",\"msgType\":14,\"body\":{\"careObjectId\":\"134815514444430058\",\"time\":1614847218218,\"status\":1},\"status\":\"200\"}";
        JSONObject jsonObject = JSON.parseObject(arg0);
        if (jsonObject.get("msg").toString().equals("Unknown Client")) {
            this.send(req);
            return;
        } else if (jsonObject.get("msg").toString().equals("RegisterSuccess")) {
            lbWatchService.startSendHeart = true;
            this.send("{\"action\": \"keepAlive\"}");
            return;
        } else if (jsonObject.get("msg").toString().equals("ConnectToWebSocketSuccess")) {
            RedisUtil.del("laiBangToken");
            this.send(req);
            return;
        }
        Integer msgType = (Integer) jsonObject.get("msgType");
        JSONObject body = JSON.parseObject(jsonObject.get("body").toString());
        /*if (!msgType.equals(6) && !msgType.equals(5)) {
            log.error("来邦数据类型("+msgType+")："+arg0);
        }*/
        if (msgType.equals(53)) {//血压血氧心率
            log.info("接收到来邦健康数据：" + arg0);
            LbWatchVO lbWatchVO = JSON.toJavaObject(body, LbWatchVO.class);
            //回复收到
            this.send("{\"req\":{\"recordId\":\"" + lbWatchVO.getRecordId() + "\",\"clientType\":7},\"action\":\"appConfirm\"}");
            lbWatchVO.setReportTime(lbWatchVO.getReportTime() * 1000);
            LbWatch entity = LbWatchConvertor.VO2Entity(lbWatchVO);
            if (StringUtil.isBlank(entity.getDeviceMac())) {
                return;
            }
            EquipmentCustom equipmentCustom = equipmentCustomService.selectEquipmentCustomByDeviceIdentity(entity.getDeviceMac());
            if (equipmentCustom != null) {
                //是否低电量
                if (lbWatchVO.getAddWearStatusDTO().getPowerStatus() == 1) {
                    warningService.insertWarning(equipmentCustom.getCustomerId(), WarningType.POWER, lbWatchVO.getDeviceMac(), EquipCategory.LB);

                }
                //是否摘除
                if (lbWatchVO.getAddWearStatusDTO().getStatus() == 2) {
                    warningService.insertWarning(equipmentCustom.getCustomerId(), WarningType.REMOVE, lbWatchVO.getDeviceMac(), EquipCategory.LB);
                    return;
                }
                entity.setCustomer_id(equipmentCustom.getCustomerId());
                LbWatchData lbWatchData = JSON.toJavaObject(JSON.parseObject(entity.getAddHealthDTO()), LbWatchData.class);
                if ((lbWatchData.getDiastolicPressure() == 0 && lbWatchData.getSystolicPressure() == 0) || (lbWatchData.getDiastolicPressure() == 255 && lbWatchData.getSystolicPressure() == 255)) {
                    return;
                }
                int i = lbWatchMapper.insertSelective(entity);
                lbWatchData.setDeviceMac(entity.getDeviceMac());
                lbWatchData.setRecordId(entity.getRecordId());
                lbWatchData.setReportTime(new Date(entity.getReportTime()));
                lbWatchData.setPid(entity.getId());
                lbWatchData.setCustomerId(entity.getCustomer_id());
                lbWatchData.setMeasureTime(new Date(lbWatchVO.getAddHealthDTO().getMeasureTime() * 1000l));
                Integer bloodOxygen = lbWatchData.getBloodOxygen();
                if (bloodOxygen > 100) {
                    lbWatchData.setBloodOxygen(bloodOxygen % 100);
                }
                lbWatchDataMapper.insertSelective(lbWatchData);
                //用于关机预警判断
                RedisUtil.set(lbWatchData.getDeviceMac(), lbWatchData, 60 * 60 * 24l);
                //健康值预警判断
                healthService.judgeIsNormalAndInsertRecord(lbWatchData);
            }

        } else if (msgType.equals(14)) {//定位
            log.info("接收到来邦定位数据：" + arg0);
            String careObjectId = (String) body.get("careObjectId");
            Equipment equipment = equipmentService.selectEquipmentByLbUserId(careObjectId);
            EquipmentCustom equipmentCustom = equipmentCustomService.selectEquipmentCustomByDeviceIdentity(equipment.getSerialNumber());
            LbWatchLoc lbWatchLoc = lbWatchService.getTrackList(careObjectId);
            lbWatchLoc.setCustomerId(equipmentCustom.getCustomerId());
            lbWatchLoc.setDeviceMac(equipment.getSerialNumber());
            LbWatchLoc loc = lbWatchLocMapper.selectLastOneByCustomerId(equipmentCustom.getCustomerId());
            if (((lbWatchLoc.getReportTime().getTime() - loc.getReportTime().getTime()) / 1000) < 60) {
                return;
            }
            lbWatchLocMapper.insertSelective(lbWatchLoc);
            //判断电子围栏
            /*ElectronicFence electronicFence = electronicFenceService.selectFenceByCustomerId(equipmentCustom.getCustomerId());
            if (StringUtil.isNotBlank(lbWatchLoc.getLgt())&&StringUtil.isNotBlank(lbWatchLoc.getLat())) {
                Point point = new Point(Double.valueOf(lbWatchLoc.getLgt()), Double.valueOf(lbWatchLoc.getLat()));
                boolean warning = electronicFenceService.isWarning(point, equipmentCustom.getCustomerId());
                if (warning) {
                    Warning locWarning = new Warning();
                    locWarning.setId(IDUtils.genItemId());
                    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String dateStr = dateFormat.format(new Date());
                    locWarning.setWarningTime(dateStr);
                    locWarning.setContent("电子围栏报警，请您注意！");
                    locWarning.setCustomerId(equipmentCustom.getCustomerId());
                    locWarning.setType("1");
                    locWarning.setState("0");
                    locWarning.setImei(equipment.getSerialNumber());
                    locWarning.setCategory(equipment.getCategory());
                    warningMapper.insertSelective(locWarning);
                }
            }*/
        } else if (msgType.equals(2)) {//报警
            this.send("{\"req\":{\"alarmId\":\"" + body.get("alarmId").toString() + "\"},\"action\":\"receiveAlarm\"}");
            //处理时间，来邦时间为秒时间戳
            Long alarmTime = Long.valueOf(body.get("alarmTime").toString()) * 1000;
            String alarmId = body.get("alarmId").toString();
            LbWatchWarn warnParam = new LbWatchWarn();
            warnParam.setAlarmId(alarmId);
            LbWatchWarn warn = lbWatchWarnMapper.selectOne(warnParam);
            LbWatchWarn lbWatchWarn = JSON.toJavaObject(body, LbWatchWarn.class);
            lbWatchWarn.setAlarmTime(new Date(alarmTime));
            EquipmentCustom equipmentCustom = equipmentCustomService.selectEquipmentCustomByDeviceIdentity(lbWatchWarn.getDeviceMac());
            lbWatchWarn.setCustomerId(equipmentCustom.getCustomerId());
            if (warn != null) {//update
                lbWatchWarn.setId(warn.getId());
                lbWatchWarnMapper.updateByPrimaryKeySelective(lbWatchWarn);
            } else {//add
                Customer customer = customerService.selectCustomerById(equipmentCustom.getCustomerId());
                //入库来邦报警表
                lbWatchWarnMapper.insertSelective(lbWatchWarn);
                //入库公共报警表
                if (lbWatchWarn.getAlarmType().equals(1)) {//SOS
                    warningService.insertWarning(equipmentCustom.getCustomerId(), WarningType.SOS, lbWatchWarn.getDeviceMac(), EquipCategory.LB);
                } else if (lbWatchWarn.getAlarmType().equals(8)) {//跌倒
                    warningService.insertWarning(equipmentCustom.getCustomerId(), WarningType.FALL, lbWatchWarn.getDeviceMac(), EquipCategory.LB);
                } else if (lbWatchWarn.getAlarmType().equals(22)) {//低电量
                    warningService.insertWarning(equipmentCustom.getCustomerId(), WarningType.POWER, lbWatchWarn.getDeviceMac(), EquipCategory.LB);
                } else if (lbWatchWarn.getAlarmType().equals(4)) {//心率
                    //自己的健康参数
                    HealthParameter selfHealthParameter = healthService.selectMapHealthParameterByCodeAndCustomerId(HealthParamCode.MB, equipmentCustom.getCustomerId());
                    //默认的健康参数
                    HealthParameter defaultHealthParameter = healthService.selectMapHealthParameterByCode(HealthParamCode.MB);
                    HealthParameter healthParameter = selfHealthParameter == null ? defaultHealthParameter : selfHealthParameter;
                    HealthWarnRecord record = new HealthWarnRecord();
                    record.setCategory(healthParameter.getCategory());
                    record.setDetail(healthParameter.getName() + " (" + lbWatchWarn.getHeartRate() + ") 异常");
                    record.setUserId(equipmentCustom.getCustomerId());
                    record.setRelateId("LbWatchData_" + (lbWatchWarn == null ? "" : lbWatchWarn.getId()));
                    record.setCreateTime(new Date());
                    record.setDefaultParameter(defaultHealthParameter.getMax());
                    record.setSelfParameter(healthParameter.getMax());
                    record.setDeviceType(EquipCategory.LB);
                    healthWarnRecordMapper.insertSelective(record);
                }
            }

        }
    }

    @Override
    public void send(String text) throws NotYetConnectedException {
        log.info("发送数据： " + text);
        try {
            super.send(text);
        } catch (Exception e) {
            RedisUtil.del("laiBangToken");
            lbWebSocketClient.reconnect();
            String req = "{\"req\":{\"clientType\":\"7\",\"id\":\"" + lbWatchService.getLaiBangToken() + "\"},\"action\":\"register\"}";
            super.send(req);
        }
    }

}
